#pragma once
#include <Math/Random.hpp>
#include <zMatrix.hpp>

namespace zzz
{
zMatrix<double, zColMajor> Rand(zuint row, zuint col);

template<typename T, typename zMajor, typename T1>
T Interpolate(const zMatrixBaseR<T,zMajor> &mat, T1 r, T1 c) {
  double row(r), col(c);
  // do the interpolation
  zuint r0=Clamp<int>(0, floor(row), mat.Size(0)-1);
  zuint r1=Clamp<int>(0, ceil(row), mat.Size(0)-1);
  zuint c0=Clamp<int>(0, floor(col), mat.Size(1)-1);
  zuint c1=Clamp<int>(0, ceil(col), mat.Size(1)-1);
  const double fractR = row - r0;
  const double fractC = col - c0;
  const T syx = mat(r0,c0);
  const T syx1 = mat(r0,c1);
  const T sy1x = mat(r1,c0);
  const T sy1x1 = mat(r1,c1);
  // normal interpolation within range
  const T tmp1 = syx  + (syx1-syx)*fractC;
  const T tmp2 = sy1x + (sy1x1-sy1x)*fractC;
  return T(tmp1 + (tmp2-tmp1)*fractR);
}

}